package com.qingzhuge.log.aspect;

import com.google.gson.Gson;
import com.qingzhuge.common.Constants;
import com.qingzhuge.common.HttpCode;
import com.qingzhuge.common.Resources;
import com.qingzhuge.common.annotation.ASysLog;
import com.qingzhuge.common.annotation.ASysLogMethod;
import com.qingzhuge.common.utils.HttpContextUtils;
import com.qingzhuge.common.utils.IpUtils;
import com.qingzhuge.common.utils.WebUtil;
import com.qingzhuge.context.SpringContext;
import com.qingzhuge.interfaces.ISysUser;
import com.qingzhuge.log.entity.SysLog;
import com.qingzhuge.log.event.SysLogEvent;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.ModelMap;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

/**
 * @author : zero.xiao
 * @description : 系统日志，切面处理类
 * @date :2018/6/8 0008 下午 15:26
 * @modified :
 * @since : 1.0.0
 */
@Aspect
public class SysLogAspect {

    @Around("@annotation(logMethod)")
    public Object around(ProceedingJoinPoint joinPoint,ASysLogMethod logMethod) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = joinPoint.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        Class<?> aClass = joinPoint.getTarget().getClass();
        //类是否有日志注解
        ASysLog classAnnotation = aClass.getAnnotation(ASysLog.class);
        if (null != classAnnotation) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            SysLog sysLog = new SysLog();
            //日志模块名称
            sysLog.setName(classAnnotation.value());
            if (logMethod != null) {
                String value = logMethod.value();
                //用户操作
                sysLog.setOperation(value);
            }
            if (result instanceof ResponseEntity) {
                ResponseEntity responseEntity = (ResponseEntity) result;
                Object body = responseEntity.getBody();
                if (body instanceof ModelMap) {
                    ModelMap map = (ModelMap) body;
                    Object code = map.get(Constants.RETURN_KEY_CODE);
                    sysLog.setCode(Integer.valueOf(code.toString()));
                    String msg;
                    if (Objects.equals(HttpCode.OK.value(), code)) {
                        sysLog.setOperation(Resources.getMessage(HttpCode.OK.message()));
                        msg = String.format("%s", map.get(Constants.RETURN_KEY_MSG));
                    } else {
                        sysLog.setOperation("操作失败");
                        msg = String.format("%s", map.get(Constants.RETURN_KEY_MSG));
                    }
                    sysLog.setMsg(msg);
                }
            }
            //请求的方法名

            String className = aClass.getName();
            String methodName = signature.getName();
            sysLog.setMethod(className + "." + methodName + "()");
            //请求的参数
            Object[] args = joinPoint.getArgs();
            try {
                String params = new Gson().toJson(args[0]);
                sysLog.setParams(params);
            } catch (Exception ignored) {

            }

            //获取request
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            //设置IP地址
            sysLog.setIp(IpUtils.getIpAddr(request));
            ISysUser user = WebUtil.getSysUser();
            if (null != user) {
                //用户名
                String username = user.getUsername();
                sysLog.setUsername(username);
            }
            sysLog.setTime(time);
            //保存系统日志
            SpringContext.publishEvent(new SysLogEvent(sysLog));
        }
        return result;
    }
}
